import type { AxiosRequestConfig } from "axios";
import TokenManager from "./TokenManager";
import request, { type ApiResponse } from "../services/request";
import userService from "./userService";

// 默认模型代码常量，用于检测是否使用默认模型
const DEFAULT_MODEL_CODE = "lke-deepseek-r1";

interface QueuedRequest<T = unknown, D = unknown> {
  url: string;
  method: "get" | "post" | "put" | "delete";
  data?: D;
  config?: AxiosRequestConfig;
  priority: number; // 优先级：数字越小优先级越高
  timestamp: number; // 请求被加入队列的时间戳
  onSuccess?: (response: ApiResponse<T>) => void; // 成功回调
  onError?: (error: unknown) => void; // 错误回调
  _skipActualRequest?: boolean; // 是否跳过实际的HTTP请求（用于聊天请求）
  _isChatRequest?: boolean; // 标记是否为聊天请求
  _requestType?: string; // 请求类型标记，便于调试和过滤
  _autoProcess?: boolean; // 是否自动处理（登录后自动执行UI回调）
}

/**
 * 请求队列管理器
 *
 * 用于管理需要登录后才能执行的API请求
 * 可以将请求加入队列，等待用户登录后按优先级顺序执行
 * @author BelovedLYC
 */
class RequestQueueManager {
  private queue: QueuedRequest[] = [];
  private isProcessing: boolean = false;
  private tokenCheckInterval: number | null = null;
  private nonChatRequests: Set<string> = new Set(); // 记录非聊天请求URL，避免重复计数

  constructor() {
    // 初始化已知的非聊天请求URL
    this.nonChatRequests.add("/ai/model/list");
    this.nonChatRequests.add("/ai/chat/session/list");

    // 监听用户登录状态变化
    userService.subscribe(this.handleUserStateChange);

    // 启动token检查计时器
    this.startTokenCheck();
  }

  /**
   * 启动token检查
   * 定期检查是否有token，如果有就处理队列
   */
  private startTokenCheck() {
    if (this.tokenCheckInterval === null) {
      this.tokenCheckInterval = window.setInterval(() => {
        if (TokenManager.getToken()) {
          this.processQueue();
        }
      }, 1000); // 每秒检查一次
    }
  }

  /**
   * 停止token检查
   */
  private stopTokenCheck() {
    if (this.tokenCheckInterval !== null) {
      clearInterval(this.tokenCheckInterval);
      this.tokenCheckInterval = null;
    }
  }

  /**
   * 判断请求是否为用户发送的聊天消息
   * @param request 请求对象
   * @returns 是否为聊天请求
   */
  private isChatMessageRequest(request: QueuedRequest): boolean {
    // 如果是已知的非聊天请求，直接返回false
    if (this.nonChatRequests.has(request.url)) {
      return false;
    }

    // 必须是POST请求且URL包含/ai/chat
    if (request.method !== "post" || !request.url.includes("/ai/chat")) {
      return false;
    }

    // 必须包含数据
    if (!request.data || typeof request.data !== "object") {
      return false;
    }

    // 数据必须包含content或message字段
    const data = request.data as Record<string, unknown>;
    return (
      (typeof data.content === "string" && data.content.trim() !== "") ||
      (typeof data.message === "string" && data.message.trim() !== "") ||
      (typeof data._originalUserMessage === "string" &&
        data._originalUserMessage.trim() !== "")
    );
  }

  /**
   * 处理用户状态变化
   */
  private handleUserStateChange = () => {
    if (userService.isLoggedIn) {
      console.log("[RequestQueue] 用户已登录，准备处理请求队列");

      // 登录时检查队列中的消息数量
      const chatRequestCount = this.getChatRequestCount();
      console.log(`[RequestQueue] 当前队列中有 ${chatRequestCount} 条聊天消息`);

      // 登录成功后，确保只保留最后一条聊天消息
      if (chatRequestCount > 1) {
        const removedCount = this.keepOnlyLastChatRequest();
        console.log(
          `[RequestQueue] 用户登录后优化队列，移除了 ${removedCount} 条旧聊天消息，保留最新消息`
        );
      }

      // 处理队列
      this.processQueue();
    }
  };

  /**
   * 获取队列中聊天请求的数量
   * @returns 聊天请求数量
   */
  public getChatRequestCount(): number {
    // 使用isChatMessageRequest判断，确保只计算真正的聊天请求
    return this.queue.filter((req) => req._isChatRequest === true).length;
  }

  /**
   * 只保留最后一条聊天消息，删除之前的聊天消息
   * @returns 被移除的请求数量
   */
  public keepOnlyLastChatRequest(): number {
    // 获取所有聊天请求(已标记的)
    const chatRequests = this.queue.filter(
      (req) => req._isChatRequest === true
    );

    // 如果没有或只有一条聊天请求，不需要处理
    if (chatRequests.length <= 1) {
      return 0;
    }

    // 按时间戳排序，保留最新的一条
    chatRequests.sort((a, b) => b.timestamp - a.timestamp);
    const lastChatRequest = chatRequests[0];

    // 过滤掉其他聊天请求，保留非聊天请求和最后一条聊天请求
    const removedCount = chatRequests.length - 1;
    this.queue = this.queue.filter(
      (request) => !request._isChatRequest || request === lastChatRequest
    );

    console.log(
      `[RequestQueue] 保留最后一条聊天消息，移除了 ${removedCount} 条旧消息`
    );
    return removedCount;
  }

  /**
   * 添加请求到队列
   * @param request 请求配置
   */
  public enqueue<T = unknown, D = unknown>(
    request: Omit<QueuedRequest<T, D>, "timestamp">
  ) {
    // 1. 创建请求对象
    const queuedRequest = {
      ...request,
      timestamp: Date.now(),
      _requestType: `${request.method.toUpperCase()} ${request.url}`,
    } as QueuedRequest;

    // 2. 判断是否为聊天请求
    const isChatRequest = this.isChatMessageRequest(queuedRequest);
    queuedRequest._isChatRequest = isChatRequest;

    // 3. 如果是已知的非聊天URL，记录下来避免重复判断
    if (!isChatRequest && request.url.includes("/ai/")) {
      this.nonChatRequests.add(request.url);
    }

    // 4. 打印详细日志
    console.log(
      `[RequestQueue] 添加请求: ${queuedRequest._requestType}${
        isChatRequest ? " (聊天请求)" : ""
      }, 当前队列共${
        this.queue.length
      }个请求，其中聊天请求${this.getChatRequestCount()}个`
    );

    // 5. 如果是聊天请求，先清理历史聊天请求
    if (isChatRequest) {
      const beforeCount = this.getChatRequestCount();
      const removedCount = this.keepOnlyLastChatRequest();
      if (removedCount > 0) {
        console.log(
          `[RequestQueue] 清理历史聊天请求: ${beforeCount} -> ${this.getChatRequestCount()}`
        );
      }
    }

    // 6. 添加到队列
    this.queue.push(queuedRequest);

    // 7. 记录队列状态
    console.log(
      `[RequestQueue] 队列更新后: 共${
        this.queue.length
      }个请求，其中聊天请求${this.getChatRequestCount()}个`
    );

    // 8. 如果已登录，尝试立即处理队列
    if (TokenManager.getToken()) {
      this.processQueue();
    }
  }

  /**
   * 将队列中的聊天消息标记为已确认保留
   * 确保这些消息在登录后不会自动显示UI
   */
  public markQueuedMessageAsConfirmed(): void {
    let updatedCount = 0;

    // 遍历队列，查找聊天请求并标记
    this.queue.forEach((request) => {
      if (request._isChatRequest === true) {
        // 如果是聊天请求且有数据
        if (request.data && typeof request.data === "object") {
          const data = request.data as Record<string, unknown>;

          // 标记为不自动处理
          data._autoProcess = false;
          updatedCount++;

          console.log(
            `[RequestQueue] 已将消息标记为手动确认: ${
              typeof data._originalUserMessage === "string"
                ? data._originalUserMessage.substring(0, 30) + "..."
                : "未知内容"
            }`
          );
        }
      }
    });

    console.log(`[RequestQueue] 已标记 ${updatedCount} 条消息为手动确认模式`);
  }

  /**
   * 处理队列中的请求
   */
  public async processQueue() {
    // 防止并发处理
    if (this.isProcessing || this.queue.length === 0) {
      return;
    }

    this.isProcessing = true;

    try {
      // 获取token状态
      const hasToken = !!TokenManager.getToken();

      if (!hasToken) {
        console.log("[RequestQueue] 无token，暂停处理队列");
        this.isProcessing = false;
        return;
      }

      console.log(
        `[RequestQueue] 开始处理队列，共 ${
          this.queue.length
        } 个请求，其中聊天请求 ${this.getChatRequestCount()} 个`
      );

      // 登录时确保只保留最后一条聊天消息
      const removedCount = this.keepOnlyLastChatRequest();
      if (removedCount > 0) {
        console.log(
          `[RequestQueue] 登录处理前优化队列，移除了 ${removedCount} 条旧聊天消息`
        );
      }

      // 按优先级排序队列
      const sortedQueue = [...this.queue].sort((a, b) => {
        // 先按优先级排序
        const priorityDiff = a.priority - b.priority;
        if (priorityDiff !== 0) return priorityDiff;

        // 优先级相同则按时间排序
        return a.timestamp - b.timestamp;
      });

      // 清空当前队列
      this.queue = [];

      // 是否已处理过聊天请求
      let hasProcessedChatRequest = false;

      // 逐一处理请求
      for (const item of sortedQueue) {
        try {
          // 判断是否是聊天请求
          const isChatRequest = item._isChatRequest === true;

          // 跳过处理条件：已处理过一个聊天请求且当前也是聊天请求
          if (hasProcessedChatRequest && isChatRequest) {
            console.log(
              `[RequestQueue] 已处理过一个聊天请求，跳过此聊天请求: ${
                item._requestType || item.url
              }`
            );
            continue;
          }

          console.log(
            `[RequestQueue] 处理请求: ${item._requestType || item.url}${
              isChatRequest ? " (聊天请求)" : ""
            }`
          );

          // 确保使用正确的字段名
          if (item.data && typeof item.data === "object" && isChatRequest) {
            // 使用类型断言来安全访问属性
            const data = item.data as Record<string, unknown>;

            // 检查是否标记为不自动处理
            const shouldAutoProcess = data._autoProcess !== false;

            if (!shouldAutoProcess) {
              console.log(
                `[RequestQueue] 此消息被标记为不自动处理，跳过UI回调: ${
                  data._originalUserMessage || data.content || "未知内容"
                }`
              );

              // 尝试删除UI回调，避免后续意外触发
              if (typeof data._uiCallback === "function") {
                delete data._uiCallback;
                console.log("[RequestQueue] 已删除消息的UI回调函数");
              }

              // 如果不自动处理，跳过此聊天请求
              continue;
            }

            // 标记已处理聊天请求
            hasProcessedChatRequest = true;

            // 将message字段转换为content字段
            if (data.message && !data.content) {
              data.content = data.message;
              delete data.message;
            }

            // 移除不必要的options字段
            if (data.options) {
              delete data.options;
            }

            // 确保有model字段，优先使用请求自带的model字段
            if (!data.model) {
              // 尝试使用全局默认模型（如果有）
              if (window._defaultModelInfo) {
                data.model = window._defaultModelInfo.accessCode;
                console.log(`[RequestQueue] 使用全局默认模型: ${data.model}`);
              } else {
                // 否则使用硬编码的默认值
                data.model = "lke-deepseek-r1";
                console.log(
                  "[RequestQueue] 使用硬编码默认模型: lke-deepseek-r1"
                );
              }
            } else {
              // 如果请求已带有model字段，检查是否需要使用更新的模型
              // 全局模型更新后，考虑替换过期的模型标识符
              if (
                window._defaultModelInfo &&
                data.model === DEFAULT_MODEL_CODE &&
                window._defaultModelInfo.accessCode !== DEFAULT_MODEL_CODE
              ) {
                console.log(
                  `[RequestQueue] 更新过期模型: ${data.model} -> ${window._defaultModelInfo.accessCode}`
                );
                data.model = window._defaultModelInfo.accessCode;
              } else {
                console.log(`[RequestQueue] 使用请求指定的模型: ${data.model}`);
              }
            }

            // 确保包含sessionId参数，即使是undefined值
            if (!("sessionId" in data)) {
              data.sessionId = undefined;
            }

            // 添加特殊标记，表示这是从队列执行的请求，方便后续处理
            data._fromQueue = true;
          }

          // 检查是否需要跳过实际的HTTP请求（聊天请求）
          if (item._skipActualRequest) {
            console.log(`[RequestQueue] 跳过HTTP请求，仅执行UI回调`);

            // 提取并执行UI回调
            if (item.data && typeof item.data === "object") {
              const data = item.data as Record<string, unknown>;

              // 检查是否标记为不自动处理
              const shouldAutoProcess = data._autoProcess !== false;

              if (!shouldAutoProcess) {
                console.log(
                  "[RequestQueue] 此消息被标记为不自动处理，跳过UI回调"
                );
                continue;
              }

              // 执行UI回调
              if (typeof data._uiCallback === "function") {
                try {
                  console.log(
                    "[RequestQueue] 执行聊天UI回调（不发送HTTP请求）"
                  );
                  // 执行UI回调
                  data._uiCallback();
                } catch (e) {
                  console.error("[RequestQueue] 执行UI回调出错:", e);
                  // 如果有错误回调，则执行
                  if (item.onError) {
                    item.onError(e);
                  }
                }
              } else {
                console.warn("[RequestQueue] 聊天请求没有UI回调函数");
              }
            }

            // 跳过发送HTTP请求
            continue;
          }

          let response;
          switch (item.method) {
            case "get":
              response = await request.get(item.url, item.config);
              break;
            case "post":
              // 检查是否是聊天请求，并且有UI回调
              if (isChatRequest && item.data && typeof item.data === "object") {
                const data = item.data as Record<string, unknown>;

                // 检查是否标记为不自动处理
                const shouldAutoProcess = data._autoProcess !== false;

                if (!shouldAutoProcess) {
                  console.log(
                    "[RequestQueue] 此消息被标记为不自动处理，跳过UI回调"
                  );
                  // 删除UI回调，但继续发送请求
                  if (typeof data._uiCallback === "function") {
                    delete data._uiCallback;
                  }
                } else {
                  // 记录详细的请求信息，帮助调试
                  console.log("[RequestQueue] 处理聊天请求，数据:", {
                    hasContent: !!data.content,
                    contentLength:
                      typeof data.content === "string"
                        ? data.content.length
                        : "not string",
                    hasFiles:
                      Array.isArray(data.files) && data.files.length > 0,
                    filesCount: Array.isArray(data.files)
                      ? data.files.length
                      : 0,
                    model: data.model,
                    sessionId: data.sessionId || "undefined",
                    fromQueue: !!data._fromQueue,
                  });

                  // 执行UI回调
                  if (typeof data._uiCallback === "function") {
                    try {
                      console.log("[RequestQueue] 执行聊天UI回调");
                      // 执行UI回调
                      data._uiCallback();
                      // 延迟50ms确保UI更新完成
                      await new Promise((resolve) => setTimeout(resolve, 50));
                      // 执行后删除回调，避免被序列化发送到服务器
                      delete data._uiCallback;
                    } catch (e) {
                      console.error("[RequestQueue] 执行UI回调出错:", e);
                    }
                  } else {
                    console.warn("[RequestQueue] 聊天请求没有UI回调函数");
                  }
                }

                // 如果请求包含原始用户消息，记录下来
                if (data._originalUserMessage) {
                  console.log(
                    "[RequestQueue] 请求包含原始用户消息:",
                    data._originalUserMessage
                  );
                  // 删除此字段，避免发送到服务器
                  delete data._originalUserMessage;
                }
              }
              response = await request.post(item.url, item.data, item.config);
              break;
            case "put":
              response = await request.put(item.url, item.data, item.config);
              break;
            case "delete":
              response = await request.delete(item.url, item.config);
              break;
          }

          // 调用成功回调
          if (item.onSuccess) {
            item.onSuccess(response);
          }
        } catch (error) {
          console.error(
            `[RequestQueue] 请求失败: ${item._requestType || item.url}`,
            error
          );

          // 调用错误回调
          if (item.onError) {
            item.onError(error);
          }
        }
      }

      console.log("[RequestQueue] 队列处理完成");
    } finally {
      this.isProcessing = false;

      // 如果队列中还有请求，继续处理
      if (this.queue.length > 0) {
        this.processQueue();
      }
    }
  }

  /**
   * 清空请求队列
   */
  public clearQueue() {
    const count = this.queue.length;
    this.queue = [];
    console.log(`[RequestQueue] 已清空队列，丢弃 ${count} 个请求`);
  }

  /**
   * 销毁队列管理器
   */
  public destroy() {
    // 停止token检查
    this.stopTokenCheck();

    // 取消用户状态监听
    // 使用subscribe返回的函数来取消订阅
    const unsubscribeFunction = userService.subscribe(
      this.handleUserStateChange
    );
    unsubscribeFunction();

    // 清空队列
    this.clearQueue();
  }

  /**
   * 获取队列中最后一条聊天消息的内容
   * @returns 最后一条消息的内容，如果没有则返回null
   */
  public getLastChatMessageContent(): string | null {
    // 获取所有聊天请求
    const chatRequests = this.queue.filter(
      (req) => req._isChatRequest === true
    );

    // 如果没有聊天请求，返回null
    if (chatRequests.length === 0) {
      return null;
    }

    // 按时间戳排序，获取最新的一条
    chatRequests.sort((a, b) => b.timestamp - a.timestamp);
    const lastChatRequest = chatRequests[0];

    // 尝试获取消息内容
    if (lastChatRequest.data && typeof lastChatRequest.data === "object") {
      const data = lastChatRequest.data as Record<string, unknown>;

      // 优先使用原始用户消息字段
      if (
        data._originalUserMessage &&
        typeof data._originalUserMessage === "string"
      ) {
        return data._originalUserMessage;
      }

      // 其次尝试content字段
      if (data.content && typeof data.content === "string") {
        return data.content;
      }

      // 最后尝试message字段
      if (data.message && typeof data.message === "string") {
        return data.message;
      }
    }

    return null;
  }
}

// 创建单例实例
const requestQueue = new RequestQueueManager();

export default requestQueue;
